package frame.security;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;

/**
 * Frame通过shiro实现动态的路径权限控制的核心。
 * 通过实现接口 AuthorizationFilter 的isAccessAllowed方法来完成具体控制。
 * 
 * @author MR.CUIPENG
 *
 */
public class PermissionsAuthorizationFilter extends AuthorizationFilter {

	/**
	 * 判断某个request是否有权限访问对应的资源。
	 * 在frame中资源是通过uri来进行唯一标识的。下面的方法中先获取request中要访问的资源路径。然后将该路径
	 * 传给 MonitorRealm进行授权许可判断。MonitorRealm中的AuthorizationInfo方法会到数据库中查询
	 * 当前用户的所能访问的所有资源。若当前请求可以在数据库中找到匹配则通过，否则没有权限。
	 */
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
       
    	Subject subject = getSubject(request, response);     
        HttpServletRequest hreq=(HttpServletRequest)request;
        
        if (subject.isPermitted(hreq.getRequestURI().replaceFirst(hreq.getContextPath()+"/", ""))) {
            return true;
        }
        return false;
    }
    /**
     * 重载 AuthorizationFilter,使某个请求没有权限时系统以json的形式返回。
     * 
     */
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {

        Subject subject = getSubject(request, response);
        // If the subject isn't identified, redirect to login URL
        if (subject.getPrincipal() == null) {
            saveRequestAndRedirectToLogin(request, response);
        } else {
            // If subject is known but not authorized, redirect to the unauthorized URL if there is one
            // If no unauthorized URL is specified, just return an unauthorized HTTP status code
            String unauthorizedUrl = getUnauthorizedUrl();
            //SHIRO-142 - ensure that redirect _or_ error code occurs - both cannot happen due to response commit:
            if (StringUtils.hasText(unauthorizedUrl)) {
//                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            	 WebUtils.toHttp(response).sendError(HttpServletResponse.SC_ACCEPTED,"{你好，这是个测试字符串}");
            } else {
            	WebUtils.toHttp(response).sendError(HttpServletResponse.SC_NOT_ACCEPTABLE,"{你好，这是个测试字符串}");
//                WebUtils.toHttp(response).getWriter().write("sadfa--------------------");
            }
        }
        return false;
    }
}
